Skip to content

Add Release workflow and prepare v0.1.0-alpha.1 - #45

Merged
Modsofthenation merged 2 commits into
mainfrom
cursor/alpha-release-f312
Aug 10, 2026
Merged

Modsofthenation merged 2 commits into
mainfrom
cursor/alpha-release-f312

Conversation

@Modsofthenation

@Modsofthenation Modsofthenation commented Aug 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds a formal Release GitHub Actions workflow and bumps the project to 0.1.0-alpha.1 so we can publish the first alpha with desktop installers attached.

Why

Desktop builds already exist via manual Desktop Installers workflow_dispatch, but they only upload Actions artifacts (30-day retention). There is no GitHub Release yet, and Settings → Check for desktop updates looks at /releases/latest.

This PR wires a release pipeline that:

  1. Runs typecheck + tests
  2. Builds Linux / macOS / Windows installers
  3. Creates tag v{version} if needed
  4. Publishes a GitHub Release (prerelease for alpha) with the installer files

How to cut the alpha (after merge)

  1. Actions → Release → Run workflow
  2. Version: 0.1.0-alpha.1
  3. Prerelease: enabled
  4. Wait for the three desktop jobs + Publish GitHub Release

Alternatively: git tag v0.1.0-alpha.1 && git push origin v0.1.0-alpha.1 on main (hyphenated tags are treated as pre-releases).

Notes

  • Rebased/merged with main after Desktop Installers was split out of CI; docs now reference both Desktop Installers (artifacts) and Release (GitHub Release).
  • The cloud agent cannot dispatch workflows or create releases with the available token (403 Resource not accessible by integration), so a human (or a GH_PAT with Actions + Contents write) must trigger the workflow after merge.
  • /releases/latest ignores pre-releases; once a non-alpha release exists, Settings update checks will pick that up.
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added automated release publishing for tagged or manually triggered builds.
    • Releases now provide Linux, macOS, and Windows desktop installers, with API packaging and validation.
    • Published releases include prerelease metadata and release notes.
  • Documentation

    • Clarified the difference between CI artifacts and published release downloads.
    • Added instructions for creating and retrieving desktop releases.
  • Chores

    • Updated application and package versions to 0.1.0-alpha.1.

Introduce a GitHub Actions Release pipeline that builds Linux/macOS/Windows
installers and publishes them as a GitHub Release (prerelease for alpha tags).
Bump package and desktop shell versions to 0.1.0-alpha.1 and document how to
trigger artifact builds vs formal releases.

Co-authored-by: Damon  <[email protected]>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6876ebce-68b9-4256-a15c-50b8643fd20c

📥 Commits

Reviewing files that changed from the base of the PR and between d758b32 and 22d8f1c.

📒 Files selected for processing (4)
  • AGENTS.md
  • README.md
  • apps/desktop/README.md
  • docs/DELIVERY.md

📝 Walkthrough

Walkthrough

The PR adds manual and tag-triggered release automation. It validates versions, tests the workspace, builds desktop installers for three platforms, smoke-tests the API sidecar, uploads artifacts, creates tags when needed, and publishes GitHub Releases. Package and desktop metadata now use 0.1.0-alpha.1.

Changes

Release delivery

Layer / File(s) Summary
Release inputs and version resolution
.github/workflows/release.yml
The workflow supports manual and tag triggers. It validates versions and exposes tag and prerelease metadata.
Validation and desktop build
.github/workflows/release.yml
The workflow runs type checks and tests, aligns package versions, configures the platform matrix, and builds Tauri installers.
Sidecar smoke test and artifact staging
.github/workflows/release.yml
The workflow launches and checks the bundled API sidecar. It stages platform installer files and uploads them as artifacts.
Tag and GitHub Release publication
.github/workflows/release.yml
The publish job downloads artifacts, creates missing manual-release tags, and publishes GitHub Release assets with prerelease metadata.
Version and release documentation alignment
apps/*/package.json, apps/desktop/src-tauri/*, packages/*/package.json, packages/mcp/src/index.ts, apps/ui/src/pages/SettingsPage.tsx, README.md, apps/desktop/README.md, AGENTS.md, docs/DELIVERY.md, package.json
Package metadata and desktop fallback data now use 0.1.0-alpha.1. Documentation describes CI artifacts and GitHub Release builds.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Release workflow
  participant meta
  participant desktop-build
  participant API-sidecar
  participant GitHub Release
  Release workflow->>meta: resolve and validate release version
  meta-->>desktop-build: provide version and prerelease metadata
  desktop-build->>API-sidecar: bundle, launch, and poll health endpoint
  API-sidecar-->>desktop-build: return health and workspace status
  desktop-build-->>Release workflow: upload installer artifacts
  Release workflow->>GitHub Release: create release and attach installers
Loading

Possibly related PRs

Suggested reviewers: cursoragent

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: adding the Release workflow and preparing version 0.1.0-alpha.1.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/alpha-release-f312

Comment @coderabbitai help to get the list of available commands.

@Modsofthenation
Modsofthenation marked this pull request as ready for review August 10, 2026 12:00
Reconcile alpha Release workflow docs with the new Desktop Installers
workflow that replaced CI workflow_dispatch builds on main.

Co-authored-by: Damon  <[email protected]>
@Modsofthenation
Modsofthenation merged commit 9c7665f into main Aug 10, 2026
1 of 2 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 21-22: Set the workflow-level permissions default to contents:
read, then add contents: write only within the publish job. Ensure the test and
desktop jobs inherit read-only contents access and retain their existing
behavior.
- Around line 12-16: Update the release workflow’s prerelease handling to derive
PRERELEASE from the validated SemVer prerelease component for both workflow
triggers, rather than trusting the manual prerelease input. Ensure versions such
as 0.1.0-alpha.1 are always marked as prereleases; alternatively, validate and
fail manual runs when the input conflicts with the version.
- Around line 241-254: Update the “Ensure release tag exists” step to validate
an existing tag’s dereferenced commit against HEAD using the tag-resolution
logic around git rev-parse. Keep the existing success path when they match, but
fail the workflow with a clear mismatch message before uploading when the tag
points to a different commit; retain tag creation and pushing for missing tags.
- Around line 37-60: Update the step identified by id "out" to pass
inputs.version via the RELEASE_VERSION environment variable and branch on
$GITHUB_EVENT_NAME, avoiding direct GitHub-expression interpolation in Bash.
Read the dispatch version from "$RELEASE_VERSION" before stripping an optional
v, and replace the current regex with strict SemVer validation that rejects
leading-zero numeric components, numeric prerelease identifiers with leading
zeros, and empty or repeated prerelease segments while preserving valid build
metadata.
- Around line 68-72: Update every uses reference in the release workflow,
including actions/checkout, pnpm/action-setup, and actions/setup-node, to a full
immutable commit SHA instead of a tag or branch ref. Add an adjacent comment
documenting each pinned action’s intended version, preserving the current
versions, and configure the repository’s automated dependency updater to
maintain these SHA pins.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cd44f141-3ee0-4c4b-9bd9-bec08f70e1cb

📥 Commits

Reviewing files that changed from the base of the PR and between afc0fa4 and d758b32.

📒 Files selected for processing (15)
  • .github/workflows/release.yml
  • README.md
  • apps/api/package.json
  • apps/desktop/README.md
  • apps/desktop/package.json
  • apps/desktop/src-tauri/Cargo.toml
  • apps/desktop/src-tauri/tauri.conf.json
  • apps/ui/package.json
  • apps/ui/src/pages/SettingsPage.tsx
  • docs/DELIVERY.md
  • package.json
  • packages/db/package.json
  • packages/mcp/package.json
  • packages/mcp/src/index.ts
  • packages/shared/package.json

Comment on lines +12 to +16
prerelease:
description: "Mark the GitHub Release as a pre-release"
required: true
type: boolean
default: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Derive prerelease status from the release version.

A manual run can publish 0.1.0-alpha.1 with prerelease: false. That release can then become /releases/latest, despite the desktop updater excluding prereleases.

Derive PRERELEASE from the validated SemVer prerelease component for both triggers. Alternatively, fail when the manual input conflicts with the version.

Also applies to: 41-52

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 12 - 16, Update the release
workflow’s prerelease handling to derive PRERELEASE from the validated SemVer
prerelease component for both workflow triggers, rather than trusting the manual
prerelease input. Ensure versions such as 0.1.0-alpha.1 are always marked as
prereleases; alternatively, validate and fail manual runs when the input
conflicts with the version.

Comment on lines +21 to +22
permissions:
contents: write

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Restrict repository write permission to the publish job.

test and desktop do not create tags or releases. They currently receive contents: write.

Set the workflow default to contents: read. Grant contents: write only to publish.

Proposed fix
 permissions:
-  contents: write
+  contents: read
...
   publish:
     name: Publish GitHub Release
     needs: [meta, desktop]
     runs-on: ubuntu-latest
+    permissions:
+      contents: write

Also applies to: 225-228

🧰 Tools
🪛 zizmor (1.29.0)

[error] 22-22: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level

(excessive-permissions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 21 - 22, Set the workflow-level
permissions default to contents: read, then add contents: write only within the
publish job. Ensure the test and desktop jobs inherit read-only contents access
and retain their existing behavior.

Source: Linters/SAST tools

Comment on lines +37 to +60
- id: out
shell: bash
run: |
set -euo pipefail
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION="${{ inputs.version }}"
VERSION="${VERSION#v}"
PRERELEASE="${{ inputs.prerelease }}"
else
TAG_NAME="${GITHUB_REF_NAME}"
VERSION="${TAG_NAME#v}"
if [[ "$VERSION" == *"-"* ]]; then
PRERELEASE=true
else
PRERELEASE=false
fi
fi
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-].+)?$ ]]; then
echo "Invalid version: $VERSION" >&2
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
echo "prerelease=$PRERELEASE" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- workflow files ---'
git ls-files '.github/workflows/*'

printf '%s\n' '--- release workflow outline/context ---'
wc -l .github/workflows/release.yml
cat -n .github/workflows/release.yml | sed -n '1,180p'

printf '%s\n' '--- relevant references ---'
rg -n -C 3 'inputs\.version|GITHUB_EVENT_NAME|GITHUB_REF_NAME|VERSION=|GITHUB_OUTPUT|package\.json|npm version|tag|release' .github/workflows/release.yml

printf '%s\n' '--- behavioral probe: generated Bash from the current interpolation ---'
python3 - <<'PY'
import subprocess

template = r'''set -euo pipefail
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
  VERSION="${{ inputs.version }}"
  VERSION="${VERSION#v}"
else
  TAG_NAME="${GITHUB_REF_NAME}"
  VERSION="${TAG_NAME#v}"
fi
printf 'VERSION=<%s>\n' "$VERSION"
'''

values = {
    "benign": "v1.2.3",
    "quote": '"; printf "INJECTED"; #',
    "command_substitution": '$(printf INJECTED)',
    "newline": '1.2.3\nprintf INJECTED\n#',
}
for name, value in values.items():
    generated = template.replace("${{ inputs.version }}", value)
    result = subprocess.run(
        ["bash", "-c", generated],
        text=True,
        capture_output=True,
        env={"GITHUB_REF_NAME": "v9.9.9"},
    )
    print(f"[{name}] exit={result.returncode}")
    print("stdout:", repr(result.stdout))
    print("stderr:", repr(result.stderr))
PY

Repository: Modsofthenation/PerformanceReviewManager

Length of output: 13281


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import subprocess

current = r'''set -euo pipefail
if [[ "workflow_dispatch" == "workflow_dispatch" ]]; then
  VERSION="${INPUT_VERSION}"
  VERSION="${VERSION#v}"
  printf 'VERSION=<%s>\n' "$VERSION"
fi
'''

direct_template = r'''set -euo pipefail
if [[ "workflow_dispatch" == "workflow_dispatch" ]]; then
  VERSION="${{ inputs.version }}"
  VERSION="${VERSION#v}"
  printf 'VERSION=<%s>\n' "$VERSION"
fi
'''

env_template = r'''set -euo pipefail
if [[ "workflow_dispatch" == "workflow_dispatch" ]]; then
  VERSION="${RELEASE_VERSION#v}"
  printf 'VERSION=<%s>\n' "$VERSION"
fi
'''

values = {
    "benign": "v1.2.3",
    "command_substitution": '$(printf INJECTED)',
    "quote_and_command": '"; printf INJECTED; #',
    "newline_command": '1.2.3\nprintf INJECTED\n#',
}

for name, value in values.items():
    direct = direct_template.replace("${{ inputs.version }}", value)
    direct_result = subprocess.run(
        ["bash", "-c", direct],
        text=True,
        capture_output=True,
        env={"PATH": "/usr/bin:/bin"},
    )
    env_result = subprocess.run(
        ["bash", "-c", env_template],
        text=True,
        capture_output=True,
        env={"PATH": "/usr/bin:/bin", "RELEASE_VERSION": value},
    )
    print(f"[{name}] direct exit={direct_result.returncode}")
    print(f"direct stdout={direct_result.stdout!r}")
    print(f"direct stderr={direct_result.stderr!r}")
    print(f"[{name}] env exit={env_result.returncode}")
    print(f"env stdout={env_result.stdout!r}")
    print(f"env stderr={env_result.stderr!r}")
PY

printf '%s\n' '--- current regex versus strict SemVer-shaped cases ---'
python3 - <<'PY'
import re

current = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+([.-].+)?$')
strict = re.compile(
    r'^(0|[1-9][0-9]*)\.'
    r'(0|[1-9][0-9]*)\.'
    r'(0|[1-9][0-9]*)'
    r'(?:-('
    r'(?:0|[1-9][0-9]*|'
    r'[0-9]*[A-Za-z-][0-9A-Za-z-]*'
    r')(?:\.'
    r'(?:0|[1-9][0-9]*|'
    r'[0-9]*[A-Za-z-][0-9A-Za-z-]*'
    r'))*)?'
    r'(?:\+'
    r'[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$'
)

cases = [
    "1.2.3",
    "0.1.0-alpha.1",
    "1.2.3+build.7",
    "1.2.3-alpha+build.7",
    "01.2.3",
    "1.2.3-01",
    "1.2.3.",
    "1.2.3.foo",
    "1.2.3-alpha..1",
]
for value in cases:
    print(f"{value:24} current={bool(current.fullmatch(value))} strict={bool(strict.fullmatch(value))}")
PY

Repository: Modsofthenation/PerformanceReviewManager

Length of output: 1742


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import re

workflow_pattern = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+([.-].+)?$')
cases = [
    ("1.2.3", True),
    ("0.1.0-alpha.1", True),
    ("1.2.3+build.7", False),
    ("1.2.3-alpha+build.7", True),
    ("01.2.3", False),
    ("1.2.3-01", False),
    ("1.2.3.", False),
    ("1.2.3.foo", False),
    ("1.2.3-alpha..1", False),
]
for value, strict_semver_expected in cases:
    accepted = bool(workflow_pattern.fullmatch(value))
    print(f"{value:24} workflow_regex={accepted} strict_semver_expected={strict_semver_expected}")
PY

printf '%s\n' '--- exact Bash validation behavior ---'
for value in '1.2.3+build.7' '01.2.3' '1.2.3-01' '1.2.3.foo' '1.2.3-alpha..1'; do
  if [[ "$value" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-].+)?$ ]]; then
    result=accepted
  else
    result=rejected
  fi
  printf '%s: %s\n' "$value" "$result"
done

Repository: Modsofthenation/PerformanceReviewManager

Length of output: 987


Pass inputs.version through the step environment before validation.

inputs.version is inserted into Bash source at line 42. A value such as $(...) executes during assignment, and a quote can inject commands. Read the value from RELEASE_VERSION instead, and use $GITHUB_EVENT_NAME rather than interpolating github.event_name. Replace the current regex with strict SemVer validation; it accepts values such as 01.2.3, 1.2.3-01, and 1.2.3-alpha..1.

🧰 Tools
🪛 zizmor (1.29.0)

[error] 42-42: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 37 - 60, Update the step
identified by id "out" to pass inputs.version via the RELEASE_VERSION
environment variable and branch on $GITHUB_EVENT_NAME, avoiding direct
GitHub-expression interpolation in Bash. Read the dispatch version from
"$RELEASE_VERSION" before stripping an optional v, and replace the current regex
with strict SemVer validation that rejects leading-zero numeric components,
numeric prerelease identifiers with leading zeros, and empty or repeated
prerelease segments while preserving valid build metadata.

Source: Linters/SAST tools

Comment on lines +68 to +72
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
with:
version: 10.33.3
- uses: actions/setup-node@v7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- workflow action references ---'
rg -n '^[[:space:]]*-[[:space:]]+uses:' .github/workflows/release.yml
printf '%s\n' '--- relevant workflow sections ---'
sed -n '1,280p' .github/workflows/release.yml

Repository: Modsofthenation/PerformanceReviewManager

Length of output: 10348


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
import json
import re
import urllib.request
from pathlib import Path

workflow = Path(".github/workflows/release.yml").read_text()
refs = re.findall(r'uses:\s*([^@\s]+)@([^\s#]+)', workflow)

for repo, ref in refs:
    if "/" not in repo:
        continue
    if ref.startswith(("v", "stable")):
        kind = "heads" if ref == "stable" else "tags"
        url = f"https://api.github.com/repos/{repo}/git/ref/{kind}/{ref}"
        try:
            with urllib.request.urlopen(url) as response:
                data = json.load(response)
            obj = data.get("object", {})
            print(f"{repo}@{ref}: {kind}, type={obj.get('type')}, sha={obj.get('sha')}")
        except Exception as exc:
            print(f"{repo}@{ref}: lookup failed: {exc}")
    else:
        print(f"{repo}@{ref}: non-version ref")
PY

Repository: Modsofthenation/PerformanceReviewManager

Length of output: 2454


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
import json
import re
import subprocess
from pathlib import Path

refs = sorted(set(re.findall(
    r'uses:\s*([^@\s]+)@([^\s#]+)',
    Path(".github/workflows/release.yml").read_text(),
)))

for repo, ref in refs:
    endpoint = "heads" if ref == "stable" else "tags"
    url = f"https://api.github.com/repos/{repo}/git/ref/{endpoint}/{ref}"
    result = subprocess.run(
        ["curl", "-kfsSL", "-H", "Accept: application/vnd.github+json", url],
        text=True, capture_output=True, check=False,
    )
    try:
        data = json.loads(result.stdout)
        obj = data.get("object", {})
        print(json.dumps({
            "uses": f"{repo}@{ref}",
            "ref_type": endpoint,
            "object_type": obj.get("type"),
            "object_sha": obj.get("sha"),
            "error": data.get("message"),
        }, sort_keys=True))
    except Exception:
        print(json.dumps({
            "uses": f"{repo}@{ref}",
            "error": result.stderr.strip() or result.stdout[:200],
        }, sort_keys=True))
PY

Repository: Modsofthenation/PerformanceReviewManager

Length of output: 1570


Pin all release-pipeline actions to immutable commit SHAs.

The workflow uses version tags and the stable branch. An upstream ref change can execute unreviewed code with contents: write. Replace every uses: reference with a full commit SHA. Keep the intended version in an adjacent comment and use an automated dependency updater for future updates.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 68-68: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 72-72: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): this step

(cache-poisoning)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 68 - 72, Update every uses
reference in the release workflow, including actions/checkout,
pnpm/action-setup, and actions/setup-node, to a full immutable commit SHA
instead of a tag or branch ref. Add an adjacent comment documenting each pinned
action’s intended version, preserving the current versions, and configure the
repository’s automated dependency updater to maintain these SHA pins.

Comment on lines +241 to +254
- name: Ensure release tag exists
if: github.event_name == 'workflow_dispatch'
env:
TAG: ${{ needs.meta.outputs.tag }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists"
else
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Verify the existing tag points to the built commit.

Line 249 only checks whether the tag exists. A manual run from another ref can upload new installers to a release whose tag identifies an older commit.

If the tag exists, compare its dereferenced commit with HEAD and fail on mismatch.

Proposed fix
-          if git rev-parse "$TAG" >/dev/null 2>&1; then
-            echo "Tag $TAG already exists"
+          if git rev-parse -q --verify "refs/tags/$TAG^{commit}" >/dev/null; then
+            TAG_COMMIT="$(git rev-list -n 1 "$TAG")"
+            HEAD_COMMIT="$(git rev-parse HEAD)"
+            if [[ "$TAG_COMMIT" != "$HEAD_COMMIT" ]]; then
+              echo "Tag $TAG points to $TAG_COMMIT, but this build uses $HEAD_COMMIT" >&2
+              exit 1
+            fi
+            echo "Tag $TAG already exists at the built commit"
           else
             git tag -a "$TAG" -m "Release $TAG"
             git push origin "$TAG"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Ensure release tag exists
if: github.event_name == 'workflow_dispatch'
env:
TAG: ${{ needs.meta.outputs.tag }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists"
else
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"
fi
- name: Ensure release tag exists
if: github.event_name == 'workflow_dispatch'
env:
TAG: ${{ needs.meta.outputs.tag }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]`@users.noreply.github.com`"
if git rev-parse -q --verify "refs/tags/$TAG^{commit}" >/dev/null; then
TAG_COMMIT="$(git rev-list -n 1 "$TAG")"
HEAD_COMMIT="$(git rev-parse HEAD)"
if [[ "$TAG_COMMIT" != "$HEAD_COMMIT" ]]; then
echo "Tag $TAG points to $TAG_COMMIT, but this build uses $HEAD_COMMIT" >&2
exit 1
fi
echo "Tag $TAG already exists at the built commit"
else
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 241 - 254, Update the “Ensure
release tag exists” step to validate an existing tag’s dereferenced commit
against HEAD using the tag-resolution logic around git rev-parse. Keep the
existing success path when they match, but fail the workflow with a clear
mismatch message before uploading when the tag points to a different commit;
retain tag creation and pushing for missing tags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants